
#ifndef MY_AT_H
#define MY_AT_H

#include "mytypes.h"
#include "..\com_uart.h"
#include "..\..\rtos\rtos.h"

#define AT_OBJ_BUF_SIZE       1600   //SAT_Obj->r_buf的大小
#define AT_EXEC_BUF_SIZE      64     //SAT_ExecObj->content的大小
#define AT_CHANNEL_NUM        6      //通道个数,也是可建立的如TCP等连接的最大个数
#define AT_CHANNEL_BUF_SIZE   2048   //每个通道的缓冲区大小

/*<串口参数结构体*/
typedef struct{
    int uart_no;
    uInt baud;
    uChar databit;
    uChar stopbit;
    uChar parity;
    uChar rsv;
}SAT_Uart;

/*<AT状态*/
typedef enum{
    AT_EXEC_NONE,
    AT_EXEC_OK,      //执行成功
    AT_EXEC_ERROR,   //执行失败
}EAT_Status;

/*<事件结构体*/
typedef void (*event_func)(void);
typedef struct{
    const char *event_str; //触发事件的字符串
    event_func callback;   //触发事件后调用的回调函数
}SAT_Event;

/*<通道结构体*/
typedef struct{
    int used;  //通道是否已被使用
    int  fd;   //该通道绑定的句柄
    uChar *data;
    uInt rp;   //指向要读出下一个字节的位置
    uInt wp;   //指向下一个字节要写入的位置
    uInt size;
    uInt inited;
}SAT_Channel;

/*<AT命令执行核心结构体*/
typedef struct{
    int status;                     //执行结果, EAT_Status
    char content[AT_EXEC_BUF_SIZE]; //命令执行后返回的内容
    int  index;                     //content存放的有效字节数
}SAT_ExecObj;

/*<AT框架核心结构体*/
typedef struct{
    int   have_inited;   //已对该结构体初始化后,此值为1.再次对该结构体初始化,只初始化串口部分 

    int   uart_no;

    //任务同步
    uInt  mutex;
    uInt  sem;   //在AT_parse_task()中等待,在指令执行函数中发送.
    
    //表示结尾的字符串
    const char *tail;
    int  tail_size; //结尾字符串的字节数
    
    //接收缓存信息
    char  r_buf[AT_OBJ_BUF_SIZE];
    int   r_size;
    int   r_index;

    //指令执行相关
    SAT_ExecObj *exec;         //当前执行指令的SAT_ExecObj对象指针
    uInt  exec_sem;            //信号量.在指令执行函数中等待,  在AT_parse_task()中发送. 
    const char *exec_expect;   //期望的内容.若为MY_NULL表示没有期望收到的内容.
    int   exec_tail_num;       //期望的结尾数.0表示不关心有多少个结尾.
    int   exec_tail_count;     //自执行指令起,收到的结尾总数.(exec_tail_num不为0时才有效).
    //int   exec_content_size;   //指令执行结果有多少个字节.
    int   exec_finish;         //1表示exec的动作执行完毕.0表示还未执行完毕.

    //事件相关
    SAT_Event *event;   //事件
    int   event_num;    //事件个数

    //通道相关
    SAT_Channel chan[AT_CHANNEL_NUM];
}SAT_Obj;


#ifdef __cplusplus
extern "C" {
#endif

int AT_set_tail(SAT_Obj *handle, const char *tail);

int AT_exec_expect_none(SAT_Obj *handle, SAT_ExecObj *exec, const void *cmd, int cmd_len, int wait_time);
int AT_exec_expect_tail(SAT_Obj *handle, SAT_ExecObj *exec, const void *cmd, int cmd_len, int tail_num, int wait_time);
int AT_exec_expect_data(SAT_Obj *handle, SAT_ExecObj *exec, const void *cmd, int cmd_len, const char *expect_data, int wait_time);
int AT_exec_expect_all (SAT_Obj *handle, SAT_ExecObj *exec, const void *cmd, int cmd_len, const char *expect_data, int tail_num, int wait_time);

int AT_event_continue_read(SAT_Obj *handle);
char *AT_event_get_buffer(SAT_Obj *handle, int *len);

int AT_channel_bind(SAT_Obj *handle, int fd);
int AT_channel_unbind(SAT_Obj *handle, int fd);
int AT_channel_write(SAT_Obj *handle, int fd, void *data, int size);
int AT_channel_read(SAT_Obj *handle, int fd, void *data, int size);
int AT_channel_read_timeout(SAT_Obj *handle, int fd, void *data, int size, int timeout);

int AT_init(SAT_Obj *handle, SAT_Uart *uart, const char *module_name, SAT_Event *event_table, uInt event_num);

#ifdef __cplusplus
}
#endif

#endif


